package com.loong.android.tools;

import static android.app.Activity.RESULT_OK;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.hardware.camera2.CameraManager;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.text.TextUtils;

import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;

import com.loong.android.LonApp;
import com.loong.android.LonWin;
import com.loong.android.WinLife;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;

public class Camera {

    /**
     * 调用系统的拍照功能进行拍照
     *
     * @param context       上下文
     * @param photoSavePath 照片保存路径
     * @param event         拍照事件回调
     */
    public static void takePhoto(Context context, String photoSavePath, TakePhotoEvent event) {
        if (!(context instanceof Activity)) return;
        final Activity activity = (Activity) context;
        if (TextUtils.isEmpty(photoSavePath)) return;
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Uri contentUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            contentUri = FileProvider.getUriForFile(context, LonApp.getFileAuthority(), new File(photoSavePath));
        } else contentUri = Uri.fromFile(new File(photoSavePath));
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
        activity.startActivityForResult(takePictureIntent, 0);
        if (activity instanceof LonWin) {
            final String listenerName = Camera.class.getCanonicalName() + "takePhoto" + System.currentTimeMillis();
            ((LonWin) activity).addWinLifeListener(listenerName, new WinLife() {
                @Override
                public void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
                    super.onActivityResult(requestCode, resultCode, intent);
                    if(requestCode != 0) return;
                    ((LonWin) activity).removeWinLifeListener(listenerName);
                    if (event != null) {
                        event.onComplete(resultCode == RESULT_OK, photoSavePath);
                    }
                }
            });
        }
    }

    /**
     * 判断是否支持闪光灯
     *
     * @param context 上下文
     */
    public static boolean isSupportFlashLight(Context context) {
        final PackageManager pm = context.getPackageManager();
        final FeatureInfo[] features = pm.getSystemAvailableFeatures();
        for (final FeatureInfo f : features) {
            if (PackageManager.FEATURE_CAMERA_FLASH.equals(f.name)) { // 判断设备是否支持闪光灯
                return true;
            }
        }
        return false;
    }

    /**
     * 开启闪光灯，需要权限：android.permission.CAMERA
     *
     * @param context 上下文
     */
    public static void openFlashLight(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            try {
                CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
                String[] cameraIdList = cameraManager.getCameraIdList();
                if (cameraIdList == null || cameraIdList.length <= 0) return;
                cameraManager.setTorchMode(cameraIdList[0], true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                android.hardware.Camera camera = android.hardware.Camera.open();
                final android.hardware.Camera.Parameters parameters = camera.getParameters();
                parameters.setFlashMode(android.hardware.Camera.Parameters.FLASH_MODE_TORCH);
                camera.setParameters(parameters);
                camera.startPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭闪光灯，需要权限：android.permission.CAMERA
     *
     * @param context 上下文
     */
    public static void closeFlashLight(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            try {
                try {
                    CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
                    String[] cameraIdList = cameraManager.getCameraIdList();
                    if (cameraIdList == null || cameraIdList.length <= 0) return;
                    cameraManager.setTorchMode(cameraIdList[0], false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                android.hardware.Camera camera = android.hardware.Camera.open();
                android.hardware.Camera.Parameters parameters = camera.getParameters();
                parameters.setFlashMode(android.hardware.Camera.Parameters.FLASH_MODE_OFF);
                camera.setParameters(parameters);
                camera.release();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 更新相册
     *
     * @param context    上下文
     * @param photoPaths 照片路径
     */
    public static void updateGallery(Context context, String... photoPaths) {
        MediaScannerConnection.scanFile(context, photoPaths, null, null);
    }

    /**
     * 将图片保存到相册
     *
     * @param context     上下文
     * @param imagePath   图片路径
     * @param name        名称
     * @param description 描述
     */
    public static void saveToGallery(Context context, String imagePath, String name, String description) {
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(), imagePath, name, description);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将图片保存到相册
     *
     * @param context     上下文
     * @param bitmap      图片的位图数据
     * @param title       标题
     * @param description 描述
     */
    public static void saveToGallery(Context context, Bitmap bitmap, String title, String description) {
        MediaStore.Images.Media.insertImage(context.getContentResolver(), bitmap, title, description);
    }

    /**
     * 调用系统的照片裁剪功能对照片进行裁剪
     * aspectX 和 aspectY 表示图片裁剪的比例值，若其中一个<=0，则表示不设置裁剪比例，用户可以按照任何比例进行裁剪。
     * outputWidth 和 outputHeight 表示限制输入图片的宽高，若其中一个<=0，则表示不限制输出尺寸，按照原图裁剪出来的尺寸保存。
     *
     * @param context      上下文
     * @param imagePath    需要裁剪的照片路径
     * @param cropSavePath 裁剪后的保存路径
     * @param aspectX      水平方向的裁剪比例值
     * @param aspectY      垂直方向的裁剪比例
     * @param outputWidth  输出图片的宽度
     * @param outputHeight 输出图片的高度
     * @param event        裁剪事件回调
     */
    public static void photoCrop(Context context, String imagePath, final String cropSavePath,
                                 int aspectX, int aspectY, int outputWidth, int outputHeight, CropEvent event) {
        if (!(context instanceof Activity)) return;
        Activity activity = (Activity) context;
        if (TextUtils.isEmpty(imagePath)) return;
        if (TextUtils.isEmpty(cropSavePath)) return;
        Intent intent = new Intent("com.android.camera.action.CROP");
        Uri contentUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            contentUri = FileProvider.getUriForFile(context, LonApp.getFileAuthority(), new File(imagePath));
        } else contentUri = Uri.fromFile(new File(imagePath));
        if (contentUri == null) return;
        intent.setDataAndType(contentUri, "image/*");
        // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
        intent.putExtra("crop", "true");
        intent.putExtra("scale", true);// 去黑边
        intent.putExtra("scaleUpIfNeeded", true);// 去黑边
        if (aspectX > 0 && aspectY > 0) {
            intent.putExtra("aspectX", aspectX);
            intent.putExtra("aspectY", aspectY);
        }
        if (outputWidth > 0 && outputHeight > 0) {
            intent.putExtra("outputX", outputWidth);
            intent.putExtra("outputY", outputHeight);
        }
        //intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);

        Uri contentUriCrop;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            contentUriCrop = FileProvider.getUriForFile(context, LonApp.getFileAuthority(), new File(cropSavePath));
        } else contentUriCrop = Uri.fromFile(new File(cropSavePath));

        intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUriCrop);
        intent.putExtra("return-data", false);//设置为不返回数据

        //重要！！！添加权限，不然裁剪完后报"保存时发生错误，保存失败"
        List<ResolveInfo> resInfoList = null;
        PackageManager pm = activity.getPackageManager();
        if(pm != null && (resInfoList = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)) != null) {
            for (ResolveInfo resolveInfo : resInfoList) {
                String packageName = resolveInfo.activityInfo.packageName;
                activity.grantUriPermission(packageName, contentUriCrop,
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
        }

        activity.startActivityForResult(intent, 0);
        if (activity instanceof LonWin) {
            final String listenerName = Camera.class.getCanonicalName() + "photoCrop" + System.currentTimeMillis();
            ((LonWin) activity).addWinLifeListener(listenerName, new WinLife() {
                @Override
                public void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
                    super.onActivityResult(requestCode, resultCode, intent);
                    if(requestCode != 0) return;
                    ((LonWin) activity).removeWinLifeListener(listenerName);
                    if (event != null) {
                        event.onComplete(resultCode == RESULT_OK, cropSavePath);
                    }
                }
            });
        }
    }

    /**
     * 调用系统录制功能录制视频
     *
     * @param context 上下文
     * @param videoSavePath 视频保存地址
     * @param limitTime 录制视频的限制时间，单位为秒。若设置值<=0，则表示不限制录制时间。
     * @param limitSize 录制视频的限制大小，单位为字节。
     * @param quality 录制视频的质量，0表示低质量；1表示高质量
     * @param event 录制视频的事件回调
     */
    public static void videoRecord(Context context, String videoSavePath, long limitTime, long limitSize, int quality, VideoRecordEvent event) {
        if (!(context instanceof Activity)) return;
        Activity activity = (Activity) context;
        if (TextUtils.isEmpty(videoSavePath)) return;
        quality = quality == 0 ? 0 : 1;
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        if(limitTime > 0) {
            //限制录制时间
            intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, limitTime);
        }
        if(limitSize > 0) {
            //限制录制大小
            intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, limitSize);
        }
        Uri contentUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            contentUri = FileProvider.getUriForFile(activity, LonApp.getFileAuthority(), new File(videoSavePath));
        } else contentUri = Uri.fromFile(new File(videoSavePath));
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, quality);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
        activity.startActivityForResult(intent, 0);
        if (activity instanceof LonWin) {
            final String listenerName = Camera.class.getCanonicalName() + "videoRecord" + System.currentTimeMillis();
            ((LonWin) activity).addWinLifeListener(listenerName, new WinLife() {
                @Override
                public void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
                    super.onActivityResult(requestCode, resultCode, intent);
                    if(requestCode != 0) return;
                    ((LonWin) activity).removeWinLifeListener(listenerName);
                    if (event != null) {
                        event.onComplete(resultCode == RESULT_OK, videoSavePath);
                    }
                }
            });
        }
    }


    /**
     * 视频录像的接口事件
     */
    public abstract static class CropEvent {
        /**
         * 裁剪完毕
         *
         * @param result   结果
         * @param cropPath 裁剪得到的文件路径
         */
        public void onComplete(boolean result, String cropPath) {

        }
    }

    /**
     * 视频录像的接口事件
     */
    public abstract static class VideoRecordEvent {
        /**
         * 录像完毕
         *
         * @param result        结果
         * @param videoFilePath 录制的视频文件路径
         */
        public void onComplete(boolean result, String videoFilePath) {

        }
    }

    /**
     * 拍照的接口事件
     */
    public abstract static class TakePhotoEvent {
        /**
         * 拍照完毕
         *
         * @param result        结果
         * @param photoFilePath 照片的文件路径
         */
        public void onComplete(boolean result, String photoFilePath) {

        }
    }
}
